package edu.hku.c3330.hkucompanion;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import edu.hku.c3330.hkucompanion.manager.Assessment;
import edu.hku.c3330.hkucompanion.manager.CalendarUtils;
import edu.hku.c3330.hkucompanion.manager.Course;
import edu.hku.c3330.hkucompanion.manager.CourseManager;
import edu.hku.c3330.hkucompanion.manager.DataManager;
//import edu.hku.c3330.hkucompanion.manager.Duration;
import edu.hku.c3330.hkucompanion.manager.Event;
import edu.hku.c3330.hkucompanion.manager.EventManager;
import edu.hku.c3330.hkucompanion.manager.Assessment.AssessmentType;
//import edu.hku.c3330.hkucompanion.manager.Event.RecurrenceDateTime;


import android.accounts.Account;
import android.accounts.AccountManager;
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SyncAdapterType;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.CalendarContract.Calendars;
import android.provider.CalendarContract.Events;
import android.provider.CalendarContract.Reminders;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;

@SuppressLint("SimpleDateFormat")
public class MainActivity extends FragmentActivity implements
ActionBar.OnNavigationListener, OnClickListener, OnItemLongClickListener {

	/**
	 * The serialization (saved instance state) Bundle key representing the
	 * current dropdown position.
	 */
	private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item";
	private static final String tag = "MainActivity";
	private Button currentMonth;
	private ImageView prevMonth;
	private ImageView nextMonth;
	private GridView calendarView;
	private GridCellAdapter adapter;
	private Calendar _calendar;
	private int month;
	private int year;
	//private final DateFormat dateFormatter = new DateFormat();
	private static final String dateTemplate = "MMMM yyyy";
	private static final String hku = "#HKUCompanion";
	
	private Spinner spinner;
	private SimpleAdapter listItemAdapter;
	private ListView listView;
	private ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>();
	private ImageView indicator;

	private int page;
	private Menu menu;
	
	boolean shouldAddEvent = true;
	boolean shouldAddCourse = true;
	boolean shouldRecreateTables = true;
	
	private List<Event> events; // Storing all events in the calendar
	private String current;
	
	//Calendar
    public static final String[] EVENT_PROJECTION = new String[] {  
        Calendars._ID,                        // 0  
        Calendars.ACCOUNT_NAME,               // 1  
        Calendars.CALENDAR_DISPLAY_NAME,      // 2  
        Calendars.OWNER_ACCOUNT               // 3
    };  
    
    // The indices for the projection array above.
    private static final int PROJECTION_ID_INDEX = 0;
    private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;
    private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;
    private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		// Set up the action bar to show a drop-down list.
		final ActionBar actionBar = getActionBar();
		actionBar.setDisplayShowTitleEnabled(false);
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

		// Set up the drop-down list navigation in the action bar.
		actionBar.setListNavigationCallbacks(
				// Specify a SpinnerAdapter to populate the drop-down list.
				new ArrayAdapter<String>(actionBar.getThemedContext(),
						android.R.layout.simple_list_item_1,
						android.R.id.text1, new String[] {
					getString(R.string.title_section1),
					getString(R.string.title_section2), }), this);
		
		
		
		//Leo's part start
		DataManager.setContext(this);
		EventManager.setContext(this);
		CourseManager.setContext(this);
		
		if (shouldRecreateTables)
		{
			DataManager.dropTables(DataManager.getInstance(this).getWritableDatabase());
			DataManager.createTables(DataManager.getInstance(this).getWritableDatabase());
		}
		
		if (shouldAddEvent)
		{
			String title, desc, loc;
			short priority;
			Calendar startDate, endDate;
			Calendar recStart, recEnd;
			//Duration eventDur, recPeriod;
			
			title = "Test event 1";
			desc = "Description for event 1";
			loc = "HKU";
			priority = 1;
			startDate = Calendar.getInstance();
			endDate = Calendar.getInstance();
			CalendarUtils.clearHMS(startDate);
			CalendarUtils.clearHMS(endDate);
			endDate.add(Calendar.DATE,5);
			
			Event testEvent1 = new Event(title, desc, loc, priority);
			testEvent1.setSingleEventDateTime(testEvent1.new SingleEventDateTime(startDate, endDate));
			EventManager.updateEvent(testEvent1);
			
			title = "Test event 2";
			desc = "Description for event 2";
			loc = "CU";
			priority = 9;
			
			startDate = Calendar.getInstance();
			endDate = Calendar.getInstance();
			recStart = Calendar.getInstance();
			recEnd = Calendar.getInstance();
			
			CalendarUtils.clearHMS(startDate);
			CalendarUtils.clearHMS(endDate);
			CalendarUtils.clearHMS(recStart);
			CalendarUtils.clearHMS(recEnd);
			
			/*
			eventDur = CalendarUtils.emptyCalendar();
			recPeriod = CalendarUtils.emptyCalendar();
			eventDur.add(Calendar.HOUR_OF_DAY, 2);
			recPeriod.add(Calendar.YEAR, 1);
			*/
			
			//eventDur = new Duration(0,0,0,2,0);
			//recPeriod = new Duration(0,0,0,0,1);
			
			startDate.add(Calendar.DATE, 2);
			endDate.add(Calendar.DATE,5);
			recStart.add(Calendar.DATE, 2);
			recEnd.add(Calendar.DATE, 5);
			
			/*Event testEvent2 = new Event(title, desc, loc, priority);
			testEvent2.addRecurrence(
					testEvent2.new SingleEventDateTime(startDate, endDate),
					testEvent2.new RecurrenceDateTime(recStart,recEnd,eventDur,recPeriod)
				);

			EventManager.updateEvent(testEvent2);
			*/
		}

		if (shouldAddCourse)
		{
			String name, desc, instructor, courseCode;
			String eventTitle, eventDesc, eventLoc;
			short priority;
			Calendar startDate, endDate;

			
			name = "Course 1";
			desc = "DESC OF COURSE 1";
			instructor = "ABSC";
			courseCode = "ABCD1234";
			Course testCourse1 = new Course(name,desc,instructor,courseCode);
			
			eventTitle = "Test course event 1";
			eventDesc = "Description for course 1";
			eventLoc = "HKU";
			priority = 1;
			startDate = Calendar.getInstance();
			endDate = Calendar.getInstance();
			CalendarUtils.clearHMS(startDate);
			CalendarUtils.clearHMS(endDate);
			endDate.add(Calendar.DATE,1);			
			Assessment assessment = new Assessment(eventTitle, eventDesc, eventLoc, priority, AssessmentType.LECTURE);
			assessment.setSingleEventDateTime(assessment.new SingleEventDateTime(startDate, endDate));
			assessment.putReference("ARef 1");
			assessment.setPriority((short)4);
			assessment.setPriority((short)9);
			assessment.putReference("ARef 2");
			
			eventTitle = "Test course event 2";
			eventDesc = "Description for course 1-2";
			eventLoc = "HKU";
			priority = 1;
			startDate = Calendar.getInstance();
			endDate = Calendar.getInstance();
			CalendarUtils.clearHMS(startDate);
			CalendarUtils.clearHMS(endDate);
			startDate.add(Calendar.DATE,2);
			endDate.add(Calendar.DATE,2);			
			Assessment assessment2 = new Assessment(eventTitle, eventDesc, eventLoc, priority, AssessmentType.TUTORIAL);
			assessment2.setSingleEventDateTime(assessment.new SingleEventDateTime(startDate, endDate));
			assessment2.putReference("BRef 1");
			assessment2.putReference("BRef 2");
			assessment2.setPriority((short)4);
			testCourse1.addAssessment(assessment);
			testCourse1.addAssessment(assessment2);
			
			CourseManager.updateCourse(testCourse1);
		}
		
		events = EventManager.getAllEvents(false ,null);
	}

	@Override
	public void onRestoreInstanceState(Bundle savedInstanceState) {
		// Restore the previously serialized current dropdown position.
		if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
			getActionBar().setSelectedNavigationItem(
					savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
		}
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		// Serialize the current dropdown position.
		outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar()
				.getSelectedNavigationIndex());
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		this.menu = menu;
		Log.d(tag, "PAge = "+page);
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	String method = "";
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		
	    switch (item.getItemId()) {
	    	case R.id.sync:
	    		AccountManager acm = AccountManager.get(getApplicationContext());
	    		Account[] acct = null;

	    		SyncAdapterType[] types = ContentResolver.getSyncAdapterTypes();
	    		for (SyncAdapterType type : types) {
	    			boolean succeed = false;
	    			acct = acm.getAccountsByType(type.accountType);
	    			for (int i = 0; i < acct.length; i++) {
	    				int p = ContentResolver.getIsSyncable(acct[i], type.authority);
	    				Log.i(tag, "account name: " + acct[i].name);
	    		        Log.i(tag, "syncable: " + String.valueOf(p));
	    		        String names[] = acct[i].name.split("@");
	    		        Log.d(tag, names[0]);
	    		        Log.d(tag, names[1]);
	    		        if (names.length == 2){
	    		        	if (names[1].equals("gmail.com")){
	    		        		syncCalendars(acct[i]);
	    		        		Context context = getApplicationContext();
	    		    	    	CharSequence text = "Tasks synced to Google Calendar successfully";
	    		    	    	int duration = Toast.LENGTH_SHORT;

	    		    	    	Toast toast = Toast.makeText(context, text, duration);
	    		    	    	toast.show();
	    		    	    	succeed = true;
	    		    	    	break;
	    		        	}
	    		        }
	    			}
	    			if (succeed)
	    				break;
	    		}
	    		return true;
	        case R.id.add:
	        	//Context context = getApplicationContext();
	        	/*
		    	CharSequence text = "Task add called";
		    	int duration = Toast.LENGTH_SHORT;

		    	*/
	        	Intent intent = new Intent(this, CourseManagerInterface.class);
	        	startActivity(intent);
		    	//Toast toast = Toast.makeText(context, text, duration);
		    	//toast.show();
	            return true;
	        case R.id.sort:
	        	
	        	LayoutInflater inflater = getLayoutInflater();
	        	View layout = inflater.inflate(R.layout.spinner_list, (ViewGroup) findViewById(R.id.dialog));
	        	spinner = (Spinner) layout.findViewById(R.id.spinner1);
				final RadioButton rb1 = (RadioButton)layout.findViewById(R.id.radio_all);
				//final RadioButton rb2 = (RadioButton)layout.findViewById(R.id.radio_course);
				final RadioButton rb3 = (RadioButton)layout.findViewById(R.id.radio_custom);
//	        	ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
//	        	        R.array.sort_methods, android.R.layout.simple_spinner_item);
//	        	adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//	        	spinner.setAdapter(adapter);
	        	
	        	
	        	
	        	
	        	AlertDialog.Builder builder = new AlertDialog.Builder(this)
	        		.setTitle("Choose an sort combination")
	        		.setView(layout);
	        	
	        	builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						
						int eventsToShow = -1;
						if (rb1.isChecked())
						{
							eventsToShow = 0;
						}
						else if (rb3.isChecked()) 
						{
							eventsToShow = 2;
						}
						
						int sortMethod = spinner.getSelectedItemPosition();
						String sortString = null;
						
						switch (sortMethod)
						{
						case 0:sortString = DataManager.EventDbConstants.START + " ASC";break;
						case 1:sortString = DataManager.EventDbConstants.PRIORITY + " ASC";break;
						case 2:sortString = DataManager.EventDbConstants.TITLE + " ASC" ;break;
						}
						
						if (eventsToShow >=0 )
						{
							updateList("",eventsToShow == 2,sortString );
						}
						
						
						Log.d(tag,Integer.valueOf(eventsToShow).toString() + "," + Integer.valueOf(sortMethod).toString());
						}
				});
	        	    
	        		
	        		builder.show();
	        default:
	            return super.onOptionsItemSelected(item);
	    }
	}
	
//	protected Dialog onCreateDialog(int id)
//    {
//        Dialog dialog;
//        dialog = new Dialog(this);
//        dialog.setContentView(R.layout.spinner_list);
//        dialog.setTitle("Choose an sort combination");
//        
//        Spinner spinner = (Spinner)dialog.findViewById(R.id.spinner1);
//        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.sort_methods, android.R.layout.simple_spinner_item);
//        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//        spinner.setAdapter(adapter);
//        spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
//
//			@Override
//			public void onItemSelected(AdapterView<?> parent, View view, int pos,
//					long id) {
//				
//				Log.d(tag, parent.getItemAtPosition(pos).toString());
//				method = parent.getItemAtPosition(pos).toString();
//			}
//
//			@Override
//			public void onNothingSelected(AdapterView<?> arg0) {
//				
//				
//			} 
//		    
//	    });
//
//        return dialog;
//    }
	
	
	
	private void syncCalendars(Account acc){
		long calID = QueryCalendar(acc);
		
		Calendar start = Calendar.getInstance();
		Calendar end = Calendar.getInstance();
		CalendarUtils.clearHMS(start);
		CalendarUtils.clearHMS(end);
		end.add(Calendar.DATE, 10);
		//List<Event> events = EventManager.getAllEvents(null);
		///*List<Event>*/ events = EventManager.getEventsByDate(false,start,end,DataManager.EventDbConstants.PRIORITY + " DESC");
		
		final ContentValues values = new ContentValues();
        final ContentResolver resolver = getContentResolver();
        
		for (Event event : events){
			if (eventExistence (event, resolver, calID) == -1){
				
		    	Date startDate = event.getSingleDateTime().start.getTime();
		    	Date endDate = event.getSingleDateTime().end.getTime();
		    	java.util.Calendar calendar = java.util.Calendar.getInstance();
				
		    	calendar.setTime(startDate);
		    	final long st = calendar.getTimeInMillis();
		    	calendar.setTime(endDate);
		    	final long et = calendar.getTimeInMillis();
				
				values.put(Events.DTSTART, st);
	            values.put(Events.DTEND, et);
	            values.put(Events.TITLE, event.getTitle());
	            values.put(Events.DESCRIPTION, hku + "-"+ Long.valueOf(event.getDatabaseId()).toString() + "\n" +event.getDescription());
	            values.put(Events.CALENDAR_ID, calID);
	            values.put(Events.EVENT_TIMEZONE, "Asia/Hong_Kong");
	            values.put(Events.EVENT_LOCATION, event.getLocation());
	            Uri uri = resolver.insert(Events.CONTENT_URI, values);
		    	long eventID = Long.parseLong(uri.getLastPathSegment());
		    	
		    	
		    	ContentResolver cr = getContentResolver();
		    	//ContentValues values = new ContentValues();
		    	values.put(Reminders.MINUTES, 60*24);
		    	values.put(Reminders.EVENT_ID, eventID);
		    	values.put(Reminders.METHOD, Reminders.METHOD_ALERT);
		    	uri = cr.insert(Reminders.CONTENT_URI, values);
			}
		}
		
		
	}
	
	private long QueryCalendar(Account acc){
    	
    	// Run query
		ContentResolver cr = this.getContentResolver();
    	Cursor cur = null;
    	Uri uri = Calendars.CONTENT_URI;   
    	String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND (" 
    	                        + Calendars.ACCOUNT_TYPE + " = ?) AND ("
    	                        + Calendars.OWNER_ACCOUNT + " = ?))";
    	String[] selectionArgs = new String[] {acc.name, "com.google", acc.name}; 
    	// Submit the query and get a Cursor object back. 
    	cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);
    	
    	long calID = -1;
    	// Use the cursor to step through the returned records
    	while (cur.moveToNext()) {
    	    
    	    String displayName = null;
    	    String accountName = null;
    	    String ownerName = null;
    	      
    	    // Get the field values
    	    calID = cur.getLong(PROJECTION_ID_INDEX);
    	    displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX);
    	    accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX);
    	    ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX);
    	    
    	    Log.i("QueryCalendar", "Calendar Display name = " + displayName);
    	    Log.i("QueryCalendar", "Owner Account name = " + ownerName);
    	    // Calendar existed
    	    if (accountName.equals(acc.name))
    	    	return calID;
    	}
    	return calID;
    }	
	
	public long eventExistence (Event event, ContentResolver resolver, long calID){
    	// Run query
		String title = event.getTitle();
    	Cursor cur = null;    	
    	Uri uri = Events.CONTENT_URI;
    	
    	String[] l_projection = new String[]{"_id","title", "dtstart", "dtend", "description", "eventLocation"};
    	cur = resolver.query(uri, l_projection, "calendar_id = ? AND description LIKE ?",
    			new String[]{
    			Long.valueOf(calID).toString(),
    			hku + "-" + Long.valueOf(event.getDatabaseId()).toString() + "%"
    			}, null);
    	
    	while (cur.moveToNext()){
    		long eventID;
    		String eventTitle = null;
    		long startTime = -1;
    		long endTime = -1;
    		String description = "";
    		String eventLocation = "";
    		eventID = cur.getLong(0);
    		eventTitle = cur.getString(1);
    		startTime = cur.getLong(2);
    		endTime = cur.getLong(3);
    		description = cur.getString(4);
    		eventLocation = cur.getString(5);
    	
    		Log.d(tag,"def"+ description);
			
    		String taskDescription[] = description.split("-");
    		String taskID[] = taskDescription[1].split("\n");
    		if (taskID[0].equals(Long.valueOf(event.getDatabaseId()).toString()) && taskDescription[0].equals(hku)){
    			
    			Date startDate = event.getSingleDateTime().start.getTime();
		    	Date endDate = event.getSingleDateTime().end.getTime();
		    	java.util.Calendar calendar = java.util.Calendar.getInstance();
				
		    	calendar.setTime(startDate);
		    	final long st = calendar.getTimeInMillis();
		    	calendar.setTime(endDate);
		    	final long et = calendar.getTimeInMillis();
		    	
		    	if (st != startTime || et != endTime || !taskID[1].equals(event.getDescription())
		    			|| !eventTitle.equals(title) || !eventLocation.equals(event.getLocation()))
		    		updateEvent(eventID, calID, event, resolver);
    			return eventID;
    		}
    		
    	}
    	return -1;
    }
	
	public static void updateEvent(long eventID, long calID, Event event, ContentResolver resolver){
    	
    	ContentValues values = new ContentValues();
		Uri updateUri = null;
		
		Date startDate = event.getSingleDateTime().start.getTime();
    	Date endDate = event.getSingleDateTime().end.getTime();
    	java.util.Calendar calendar = java.util.Calendar.getInstance();
		
    	calendar.setTime(startDate);
    	final long st = calendar.getTimeInMillis();
    	calendar.setTime(endDate);
    	final long et = calendar.getTimeInMillis();
		
		values.put(Events.DTSTART, st);
        values.put(Events.DTEND, et);
        values.put(Events.TITLE, event.getTitle());
        values.put(Events.DESCRIPTION, hku + "-"+ Long.valueOf(event.getDatabaseId()).toString() + "\n" +event.getDescription());
        values.put(Events.CALENDAR_ID, calID);
        values.put(Events.EVENT_TIMEZONE, "Asia/Hong_Kong");
        values.put(Events.EVENT_LOCATION, event.getLocation());
		
		updateUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
		int rows = resolver.update(updateUri, values, null, null);
		Log.i(tag, "Rows updated: " + rows); 
    	
    }
	
	@Override
	public boolean onNavigationItemSelected(int position, long id) {
		// When the given dropdown item is selected, show its contents in the
		// container view.
		Fragment fragment = new SectionFragment();
		Bundle args = new Bundle();
		args.putInt(SectionFragment.ARG_SECTION_NUMBER, position + 1);
		fragment.setArguments(args);
		getSupportFragmentManager().beginTransaction()
			.replace(R.id.container, fragment).commit();
		return true;
	}

	private void hideOption(int id)
	{
	    MenuItem item = menu.findItem(id);
	    item.setVisible(false);
	}

	private void showOption(int id)
	{
	    MenuItem item = menu.findItem(id);
	    item.setVisible(true);
	}
	
	/**
	 * A dummy fragment representing a section of the app, but that simply
	 * displays dummy text.
	 */
	@SuppressLint("ValidFragment")
	public class SectionFragment extends Fragment {
		/**
		 * The fragment argument representing the section number for this
		 * fragment.
		 */
		public static final String ARG_SECTION_NUMBER = "section_number";

		public SectionFragment() {
		}
		

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			
			View rootView = null;
			Context context = this.getActivity().getApplicationContext();

			page = getArguments().getInt(ARG_SECTION_NUMBER);
			switch (page)
			{
				case 1:
					hideOption(R.id.sort);
					rootView = inflater.inflate(R.layout.simple_calendar_view,
							container, false);
					rootView = setView(rootView, context);
					break;
				case 2:
					showOption(R.id.sort);
					rootView = inflater.inflate(R.layout.fragment_main_dummy,
							container, false);
					rootView = setListView(rootView, context);
					break;
				default: break;
			}
			return rootView;
		}
	}
	
	private View setListView(View rootView, Context context){
		
		listView = (ListView)rootView.findViewById(R.id.AllTaskslist);
		listItem.clear();
		//Get events from now to 10 days later
		Calendar start = Calendar.getInstance();
		Calendar end = Calendar.getInstance();
		CalendarUtils.clearHMS(start);
		CalendarUtils.clearHMS(end);
		end.add(Calendar.DATE, 10);
		//List<Event> events = EventManager.getAllEvents(null);
		///*List<Event>*/ events = 
		List<Event> m_events = EventManager.getEventsByDate(false,start,end,DataManager.EventDbConstants.PRIORITY + " DESC");
		for (Event event : m_events){
			HashMap<String, Object> taskMap = new HashMap<String, Object>();
	    	taskMap.put("time", DateFormat.format("dd-MM-yyyy -", event.getSingleDateTime().start.getTime()));
	    	taskMap.put("endtime", DateFormat.format("dd-MM-yyyy", event.getSingleDateTime().end.getTime()));
			if (event.getPriority() < 3)
			{
		    	taskMap.put("priority", Integer.toString(R.drawable.priority1));
			}
			else if (event.getPriority() <6)
			{
		    	taskMap.put("priority", Integer.toString(R.drawable.priority2));
			}
			else 
			{
		    	taskMap.put("priority", Integer.toString(R.drawable.priority3));
			}

	    	taskMap.put("title", event.getTitle());
	    	taskMap.put("location", "LE2");
    		listItem.add(taskMap);
		}
		
		listItemAdapter = new SimpleAdapter(this, listItem, R.layout.task_list,
				new String[] {"time", "endtime", "priority", "title", "location"},
				new int[] {R.id.time , R.id.endtime, R.id.priority, R.id.title, R.id.location}
			);
	    
		listView.setAdapter(listItemAdapter);
	    listView.setOnItemClickListener(itemSelected);
	    listView.setOnItemLongClickListener(this);
	    return rootView;
	}
	
	private View setView(View rootView, Context context){
		
		_calendar = Calendar.getInstance(Locale.getDefault());
		month = _calendar.get(Calendar.MONTH) + 1;
		year = _calendar.get(Calendar.YEAR);
		Log.d(tag, "Calendar Instance:= " + "Month: " + month + " " + "Year: " + year);
		
		OnClickListener mButton1_OnClickListener = new OnClickListener() {
			public void onClick(View v) {
				if (v == prevMonth) {
					if (month <= 1) {
						month = 12;
						year--;
					}
					else {
						month--;
					}
					Log.d(tag, "Setting Prev Month in GridCellAdapter: " + "Month: " + month + " Year: " + year);
					setGridCellAdapterToDate(month, year);
				}
				if (v == nextMonth) {
					if (month > 11) {
						month = 1;
						year++;
					}
					else {
						month++;
					}
					Log.d(tag, "Setting Next Month in GridCellAdapter: " + "Month: " + month + " Year: " + year);
					setGridCellAdapterToDate(month, year);
				}

			}
		};
		
		prevMonth = (ImageView) rootView.findViewById(R.id.prevMonth);
		prevMonth.setOnClickListener(mButton1_OnClickListener);

		currentMonth = (Button) rootView.findViewById(R.id.currentMonth);
		currentMonth.setText(DateFormat.format(dateTemplate, _calendar.getTime()));

		nextMonth = (ImageView) rootView.findViewById(R.id.nextMonth);
		nextMonth.setOnClickListener(mButton1_OnClickListener);

		calendarView = (GridView) rootView.findViewById(R.id.calendar);

		// Initialised
		
		adapter = new GridCellAdapter(context, R.id.calendar_day_gridcell, month, year);
		adapter.notifyDataSetChanged();
		calendarView.setAdapter(adapter);
		
		listView = (ListView)rootView.findViewById(R.id.list);
		SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
		String currentDate = format.format(new Date());
		Log.d(tag, "current Date = " + currentDate);
		current = currentDate;
		updateList(currentDate, false, null);
		return rootView;
	}
	
	public void updateList(String selectedDate, boolean customEventOnly, String sorting){
		
		listItem.clear();
	    
		//Get events from now to 10 days later
		
		List<Event> m_events;
		
		if (selectedDate == null)
		{
			
			m_events = EventManager.getAllEvents(false, null);
		}
		else
		{
			Calendar start = Calendar.getInstance();
			Calendar end = Calendar.getInstance();
			CalendarUtils.clearHMS(start);
			CalendarUtils.clearHMS(end);
			end.add(Calendar.DATE, 1);
			m_events = EventManager.getEventsByDate(false, start, end, null);
		}
		
		for (Event event : m_events){
			HashMap<String, Object> taskMap = new HashMap<String, Object>();
			
			Date date = null, startDate = null, endDate = null;
			
			String eventStartDate = DateFormat.format("dd-MM-yyyy", event.getSingleDateTime().start.getTime()).toString();
			String eventEndDate = DateFormat.format("dd-MM-yyyy", event.getSingleDateTime().end.getTime()).toString();
			
			SimpleDateFormat dateFormatter = new SimpleDateFormat("dd-MM-yyyy");
			
			try {
				date = dateFormatter.parse(selectedDate);
				startDate = dateFormatter.parse(eventStartDate);
				endDate = dateFormatter.parse(eventEndDate);
				Log.d("selected date", "date " + date);
				Log.d("start date", "date " + startDate);
				Log.d("end date", "date " + endDate);
			} catch (ParseException e) {
				e.printStackTrace();
			}
			
			
			boolean bool = false;
			if (page == 1)
				bool = ((startDate.before(date) && endDate.after(date)) ||
						selectedDate.equals(eventStartDate) || 
						selectedDate.equals(eventEndDate));
			else if (page == 2)
				bool = true;
			
			Log.d(tag, "page" + eventStartDate + "< " + selectedDate  + "< " + eventEndDate);
			Log.d(tag, "page " + page + bool +"");
			
			if (bool){
		    	taskMap.put("time", DateFormat.format("dd-MM-yyyy -", event.getSingleDateTime().start.getTime()));
		    	taskMap.put("endtime", DateFormat.format("dd-MM-yyyy", event.getSingleDateTime().end.getTime()));
				if (event.getPriority() < 3)
				{
			    	taskMap.put("priority", Integer.toString(R.drawable.priority1));
				}
				else if (event.getPriority() <6)
				{
			    	taskMap.put("priority", Integer.toString(R.drawable.priority2));
				}
				else 
				{
			    	taskMap.put("priority", Integer.toString(R.drawable.priority3));
				}
		    	taskMap.put("title", event.getTitle());
		    	taskMap.put("location", "LE2");
	    		listItem.add(taskMap);
			}
		}
		
		listItemAdapter = new SimpleAdapter(this, listItem, R.layout.task_list,
				new String[] {"time", "endtime", "priority", "title", "location"},
				new int[] {R.id.time , R.id.endtime, R.id.priority, R.id.title, R.id.location}
			);
	    
		listView.setAdapter(listItemAdapter);
	    listView.setOnItemClickListener(itemSelected);
	    listView.setOnItemLongClickListener(this);
	} 
	
	private OnItemClickListener itemSelected = new OnItemClickListener() { 
	    public void onItemClick(AdapterView<?> adview, View target, int position, long id) {
	    	
	    	
			Event event = events.get(position);
			if (event.isCustomEvent())
			{
			   	Intent intent = new Intent(MainActivity.this, EventDetail.class);
		    	intent.putExtra("EventID", event.getDatabaseId());
		    	startActivity(intent);
			}
			else
			{
				Assessment assessment = CourseManager.getAssessmentByEventId(event.getDatabaseId());
				Intent intent = new Intent(MainActivity.this, AssessmentDetail.class);
				intent.putExtra("AssessmentID", assessment.getDatabaseId());
				startActivity(intent);
			}
	    	
	 
//			Context context = MainActivity.this;
//	    	CharSequence text = "Task clicked";
//	    	int duration = Toast.LENGTH_SHORT;
//	    	Toast toast = Toast.makeText(context, text, duration);
//	    	toast.show();
		}
    };
	
	/**
	 * 
	 * @param month
	 * @param year
	 */
	private void setGridCellAdapterToDate(int month, int year) {
		adapter = new GridCellAdapter(getApplicationContext(), R.id.calendar_day_gridcell, month, year);
		_calendar.set(year, month - 1, _calendar.get(Calendar.DAY_OF_MONTH));
		currentMonth.setText(DateFormat.format(dateTemplate, _calendar.getTime()));
		adapter.notifyDataSetChanged();
		calendarView.setAdapter(adapter);
		
		SimpleDateFormat format = new SimpleDateFormat("dd");
		String currentDate = format.format(new Date()) + "-" + month + "-" + year;
		current = currentDate;
		updateList(currentDate, false, null);
	}

	@Override
	public void onDestroy()
	{
		Log.d(tag, "Destroying View ...");
		super.onDestroy();
	}

	// ///////////////////////////////////////////////////////////////////////////////////////
	// Inner Class
	public class GridCellAdapter extends BaseAdapter implements OnClickListener
	{
		private static final String tag = "GridCellAdapter";
		private final Context _context;

		private final List<String> list;
		private static final int DAY_OFFSET = 1;
		//private final String[] weekdays = new String[]{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
		//private final String[] months = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
		private final String[] months = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"};
		private final int[] daysOfMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
		private final int month, year;
		private int daysInMonth; //prevMonthDays;
		private int currentDayOfMonth;
		private int currentWeekDay;
		private Button gridcell;
		//private TextView num_events_per_day;
		//private final HashMap eventsPerMonthMap;
		private final SimpleDateFormat dateFormatter = new SimpleDateFormat("dd-MM-yyyy");

		// Days in Current Month
		public GridCellAdapter(Context context, int textViewResourceId, int month, int year) {
			super();
			this._context = context;
			this.list = new ArrayList<String>();
			this.month = month;
			this.year = year;
			
			Log.d(tag, "==> Passed in Date FOR Month: " + month + " " + "Year: " + year);
			Calendar calendar = Calendar.getInstance();
			setCurrentDayOfMonth(calendar.get(Calendar.DAY_OF_MONTH));
			setCurrentWeekDay(calendar.get(Calendar.DAY_OF_WEEK));
			Log.d(tag, "New Calendar:= " + calendar.getTime().toString());
			Log.d(tag, "CurrentDayOfWeek :" + getCurrentWeekDay());
			Log.d(tag, "CurrentDayOfMonth :" + getCurrentDayOfMonth());

			// Print Month
			printMonth(month, year);

			// Find Number of Events
			//eventsPerMonthMap = findNumberOfEventsPerMonth(year, month);
		}
		private String getMonthAsString(int i)
		{
			return months[i];
		}

//		private String getWeekDayAsString(int i)
//		{
//			return weekdays[i];
//		}

		private int getNumberOfDaysOfMonth(int i)
		{
			return daysOfMonth[i];
		}

		public String getItem(int position)
		{
			return list.get(position);
		}

		@Override
		public int getCount()
		{
			return list.size();
		}

		/**
		 * Prints Month
		 * 
		 * @param mm
		 * @param yy
		 */
		private void printMonth(int mm, int yy)
		{
			Log.d(tag, "==> printMonth: mm: " + mm + " " + "yy: " + yy);
			// The number of days to leave blank at
			// the start of this month.
			int trailingSpaces = 0;
			//int leadSpaces = 0;
			int daysInPrevMonth = 0;
			int prevMonth = 0;
			int prevYear = 0;
			int nextMonth = 0;
			int nextYear = 0;

			int currentMonth = mm - 1;
			String currentMonthName = getMonthAsString(currentMonth);
			daysInMonth = getNumberOfDaysOfMonth(currentMonth);

			//Log.d(tag, "Current Month: " + " " + currentMonthName + " having " + daysInMonth + " days.");

			// Gregorian Calendar : MINUS 1, set to FIRST OF MONTH
			GregorianCalendar cal = new GregorianCalendar(yy, currentMonth, 1);
			//Log.d(tag, "Gregorian Calendar:= " + cal.getTime().toString());

			if (currentMonth == 11)
			{
				prevMonth = currentMonth - 1;
				daysInPrevMonth = getNumberOfDaysOfMonth(prevMonth);
				nextMonth = 0;
				prevYear = yy;
				nextYear = yy + 1;
				//Log.d(tag, "*->PrevYear: " + prevYear + " PrevMonth:" + prevMonth + " NextMonth: " + nextMonth + " NextYear: " + nextYear);
			}
			else if (currentMonth == 0)
			{
				prevMonth = 11;
				prevYear = yy - 1;
				nextYear = yy;
				daysInPrevMonth = getNumberOfDaysOfMonth(prevMonth);
				nextMonth = 1;
				//Log.d(tag, "**--> PrevYear: " + prevYear + " PrevMonth:" + prevMonth + " NextMonth: " + nextMonth + " NextYear: " + nextYear);
			}
			else
			{
				prevMonth = currentMonth - 1;
				nextMonth = currentMonth + 1;
				nextYear = yy;
				prevYear = yy;
				daysInPrevMonth = getNumberOfDaysOfMonth(prevMonth);
				//Log.d(tag, "***---> PrevYear: " + prevYear + " PrevMonth:" + prevMonth + " NextMonth: " + nextMonth + " NextYear: " + nextYear);
			}

			// Compute how much to leave before before the first day of the
			// month.
			// getDay() returns 0 for Sunday.
			int currentWeekDay = cal.get(Calendar.DAY_OF_WEEK) - 1;
			trailingSpaces = currentWeekDay;

			//Log.d(tag, "Week Day:" + currentWeekDay + " is " + getWeekDayAsString(currentWeekDay));
			//Log.d(tag, "No. Trailing space to Add: " + trailingSpaces);
			//Log.d(tag, "No. of Days in Previous Month: " + daysInPrevMonth);

			if (cal.isLeapYear(cal.get(Calendar.YEAR)) && mm == 1)
			{
				++daysInMonth;
			}

			// Trailing Month days
			for (int i = 0; i < trailingSpaces; i++)
			{
				Log.d(tag, "PREV MONTH:= " + prevMonth + " => " + getMonthAsString(prevMonth) + " " + String.valueOf((daysInPrevMonth - trailingSpaces + DAY_OFFSET) + i));
				list.add(String.valueOf((daysInPrevMonth - trailingSpaces + DAY_OFFSET) + i) + "-GREY" + "-" + getMonthAsString(prevMonth) + "-" + prevYear);
			}

			// Current Month Days
			for (int i = 1; i <= daysInMonth; i++)
			{
				Log.d(currentMonthName, String.valueOf(i) + " " + getMonthAsString(currentMonth) + " " + yy);
				if (i == getCurrentDayOfMonth())
				{
					list.add(String.valueOf(i) + "-BLUE" + "-" + getMonthAsString(currentMonth) + "-" + yy);
				}
				else
				{
					list.add(String.valueOf(i) + "-WHITE" + "-" + getMonthAsString(currentMonth) + "-" + yy);
				}
			}

			// Leading Month days
			for (int i = 0; i < list.size() % 7; i++)
			{
				Log.d(tag, "NEXT MONTH:= " + getMonthAsString(nextMonth));
				list.add(String.valueOf(i + 1) + "-GREY" + "-" + getMonthAsString(nextMonth) + "-" + nextYear);
			}
		}
		
//		/**
//		 * NOTE: YOU NEED TO IMPLEMENT THIS PART Given the YEAR, MONTH, retrieve
//		 * ALL entries from a SQLite database for that month. Iterate over the
//		 * List of All entries, and get the dateCreated, which is converted into
//		 * day.
//		 * 
//		 * @param year
//		 * @param month
//		 * @return
//		 */
//		private HashMap findNumberOfEventsPerMonth(int year, int month)
//		{
//			HashMap map = new HashMap<String, Integer>();
//			// DateFormat dateFormatter2 = new DateFormat();
//			//						
//			// String day = dateFormatter2.format("dd", dateCreated).toString();
//			//
//			// if (map.containsKey(day))
//			// {
//			// Integer val = (Integer) map.get(day) + 1;
//			// map.put(day, val);
//			// }
//			// else
//			// {
//			// map.put(day, 1);
//			// }
//			return map;
//		}

		@Override
		public long getItemId(int position)
		{
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent)
		{
			View row = convertView;
			if (row == null)
			{
				LayoutInflater inflater = (LayoutInflater) _context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				row = inflater.inflate(R.layout.calendar_day_gridcell, parent, false);
			}

			// Get a reference to the Day gridcell
			gridcell = (Button) row.findViewById(R.id.calendar_day_gridcell);
			gridcell.setOnClickListener(this);

			indicator = (ImageView) row.findViewById(R.id.indicator);
			// ACCOUNT FOR SPACING

			//Log.d(tag, "Current Day: " + getCurrentDayOfMonth());
			String[] day_color = list.get(position).split("-");
			String theday = day_color[0];
			String themonth = day_color[2];
			String theyear = day_color[3];
//			if ((!eventsPerMonthMap.isEmpty()) && (eventsPerMonthMap != null))
//			{
//				if (eventsPerMonthMap.containsKey(theday))
//				{
//					//num_events_per_day = (TextView) row.findViewById(R.id.num_events_per_day);
//					Integer numEvents = (Integer) eventsPerMonthMap.get(theday);
//
//					//num_events_per_day.setText(numEvents.toString());
//				}
//			}

			// Set the Day GridCell
			gridcell.setText(theday);
			if (theday.length() == 1)
				theday = "0" + theday;
			String theDate = theday + "-" + themonth + "-" + theyear;
			gridcell.setTag(theDate);
			//Log.d(tag, "Setting GridCell " + theday + "-" + themonth + "-" + theyear);

			//Set indicator
			//Get events from now to 10 days later
			Calendar start = Calendar.getInstance();
			Calendar end = Calendar.getInstance();
			CalendarUtils.clearHMS(start);
			CalendarUtils.clearHMS(end);
			end.add(Calendar.DATE, 10);
			
			//List<Event> m_events = EventManager.getAllEvents(true,null);
			for (Event event : events){				
				
				Date date = null, startDate = null, endDate = null;
				
				String eventStartDate = DateFormat.format("dd-MM-yyyy", event.getSingleDateTime().start.getTime()).toString();
				String eventEndDate = DateFormat.format("dd-MM-yyyy", event.getSingleDateTime().end.getTime()).toString();
				
				try {
					date = dateFormatter.parse(theDate);
					startDate = dateFormatter.parse(eventStartDate);
					endDate = dateFormatter.parse(eventEndDate);
					Log.d("selected date", "date " + date);
					Log.d("start date", "date " + startDate);
					Log.d("end date", "date " + endDate);
				} catch (ParseException e) {
					e.printStackTrace();
				}
				
				
				if ((startDate.before(date) && endDate.after(date))
						 || (eventStartDate.equals(theDate))
						 || (eventEndDate.equals(theDate))){
					boolean bool = (startDate.before(date) && endDate.after(date))
							 || (eventStartDate.equals(theDate))
							 || (eventEndDate.equals(theDate));
					Log.d(tag, "abc"+ bool);
					if (event.getPriority() < 3)
					{
						indicator.setImageResource(R.drawable.indicator1);
					}
					else if (event.getPriority() <6)
					{
						indicator.setImageResource(R.drawable.indicator2);
					}
					else 
					{
						indicator.setImageResource(R.drawable.indicator3);
					}
					
				}
			}
			//
			
			if (day_color[1].equals("GREY"))
			{
				gridcell.setTextColor(Color.LTGRAY);
			}
			if (day_color[1].equals("WHITE"))
			{
				gridcell.setTextColor(Color.WHITE);
			}
			if (day_color[1].equals("BLUE"))
			{
				gridcell.setTextColor(getResources().getColor(R.color.static_text_color));
			}
			return row;
		}
		@SuppressLint("SimpleDateFormat")	
		@Override
		public void onClick(View view) {
			String selectedDate = (String) view.getTag();
			
			gridcell.setTextColor(Color.WHITE);
			
			gridcell = (Button) view.findViewById(R.id.calendar_day_gridcell);
			gridcell.setTextColor(getResources().getColor(R.color.black));
			Log.d(tag, selectedDate + "To be updated");
			current = selectedDate;
			updateList(selectedDate, false, null);
		}

		public int getCurrentDayOfMonth()
		{
			return currentDayOfMonth;
		}

		private void setCurrentDayOfMonth(int currentDayOfMonth)
		{
			this.currentDayOfMonth = currentDayOfMonth;
		}
		public void setCurrentWeekDay(int currentWeekDay)
		{
			this.currentWeekDay = currentWeekDay;
		}
		public int getCurrentWeekDay()
		{
			return currentWeekDay;
		}
	}

	@Override
	public boolean onItemLongClick(AdapterView<?> arg0, View view, int pos,
			long arg3) {
		final int _pos = pos;
		new AlertDialog.Builder(this)
        .setTitle(R.string.choose_option)
        .setItems(R.array.option_list, new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				switch(which){
					case 0: {
						Event event = events.get(_pos);
						if (event.isCustomEvent()) {
						   	Intent intent = new Intent(MainActivity.this, EventEdit.class);
					    	intent.putExtra("EditEvent", event.getDatabaseId());
					    	startActivity(intent);
						} else {
							Assessment assessment = CourseManager.getAssessmentByEventId(event.getDatabaseId());
							Intent intent = new Intent(MainActivity.this, AssessmentEditing.class);
							intent.putExtra("courseId", assessment.getCourseID());
							intent.putExtra("EditEvent", assessment.getDatabaseId());
							startActivity(intent);
						}
						break;
					}
					case 1: {
						Context context = MainActivity.this;
						CharSequence text = "";
						int duration = Toast.LENGTH_SHORT;
						
						Event event = events.get(_pos);
						if (event.isCustomEvent()) {
							EventManager.removeEvent(event);
							text = "Custom Event Deleted";
						}
						else {
							Assessment assessment = CourseManager.getAssessmentByEventId(event.getDatabaseId());
							CourseManager.removeAssessment(assessment);
							text = "Assessment Deleted";
						}
						events.remove(_pos);
						updateList(current, false, null);

				    	Toast toast = Toast.makeText(context, text, duration);
				    	toast.show();
						break;
					}
				}
			}
		})
        .show();
		return true;
	}
	
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
	}
}
